package com.xinqi.modules.course.clazz.controller.app;

import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.Param;
import com.xinqi.common.base.response.R;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.mybatis.utils.Pages;
import com.xinqi.common.satoken.utils.LoginHelper;
import com.xinqi.modules.course.clazz.dto.ClassStudentAuditData;
import com.xinqi.modules.course.clazz.dto.req.*;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentMobileResultDTO;
import com.xinqi.modules.course.clazz.service.ClassStudentService;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentAddedCountResultDTO;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentResultDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 班级学生表控制层
 *
 * @author: system
 * @date: 2023/01/17
 */
@Tag(name = "App-班级学生", description = "班级学生")
@RestController
@RequestMapping("/app/class-student")
@RequiredArgsConstructor
public class ClassStudentAppController {
    private final ClassStudentService classStudentService;

    @Operation(summary = "班级学生表-分页")
    @GetMapping("/page")
    public R<PageInfo<ClassStudentResultDTO>> page(Param pageable, ClassStudentQueryDTO dto) {
        PageInfo<ClassStudentResultDTO> page = classStudentService.page(pageable, dto);
        return R.data(page);
    }

    @Operation(summary = "班级学生列表带用户条件支持多角色-分页")
    @PostMapping("/page-list")
    public R<PageInfo<ClassStudentResultDTO>> pageList(@RequestBody ClassStudentAppQueryDTO dto) {
        PageInfo<ClassStudentResultDTO> page = classStudentService.pageListAndDesensitized(Pages.page(dto), dto);
        return R.data(page);
    }

    /**
     * 模拟主学生/关系学生
     *
     * @param id 班级学生id
     * @return ClassStudentResultDTO
     */
    @Operation(summary = "模拟主学生/关系学生-详情")
    @GetMapping("/{id}")
    public R<ClassStudentResultDTO> findById(@PathVariable("id") Long id) {
        ClassStudentResultDTO dto = classStudentService.findDetailByIdAndDesensitized(id);
        return R.data(dto);
    }

    @Operation(summary = "班级学生表-根据班级id和手机号查学生")
    @GetMapping("/{classId}/find-by-mobile")
    public R<ClassStudentResultDTO> findByClassIdAndMobile(@PathVariable("classId") Long classId, String mobile) {
        ClassStudentResultDTO dto = classStudentService.findByClassIdAndMobile(classId, mobile);
        return R.data(dto);
    }

    @Operation(summary = "新增班级学生表")
    @PostMapping
    public R<Long> insert(@Validated @RequestBody ClassStudentCreateDTO dto) {
        return R.data(classStudentService.insert(dto));
    }

    /**
     * 老师可以编辑学生的姓名、绑定手机号、学号；
     *
     * @param classStudentId 模拟主学生的班级学生id
     * @param dto            参数
     * @return R<Boolean>
     */
    @Operation(summary = "老师修改班级学生表")
    @PutMapping("/teacher-update/{classStudentId}")
    public R<Boolean> teacherUpdateMasterStudent(@Parameter(description = "模拟主学生的班级学生id", example = "100001") @PathVariable("classStudentId") Long classStudentId, @Validated @RequestBody MasterClassStudentUpdateDTO dto) {
        dto.setClassStudentId(classStudentId);
        return R.data(classStudentService.updateMasterStudent(dto), "修改成功");
    }

    /**
     * 关系用户可以可以编辑主学生的学号；
     *
     * @param classStudentId 班级ID
     * @param dto            参数
     * @return R<Boolean>
     */
    @Operation(summary = "关系用户修改班级学生表")
    @PutMapping("/relation-student-update/{classStudentId}")
    public R<Boolean> relationStudentUpdateMasterStudent(@Parameter(description = "班级ID", example = "100001") @PathVariable("classStudentId") Long classStudentId, @Validated @RequestBody MasterClassStudentUpdateDTO dto) {
        dto.setClassStudentId(classStudentId);
        return R.data(classStudentService.updateMasterStudent(dto), "修改成功");
    }

    @Operation(summary = "删除班级学生表")
    @DeleteMapping("/{id}")
    public R<Boolean> delete(@PathVariable("id") Long id) {
        return R.data(classStudentService.deleteById(id), "删除成功");
    }

    @Operation(summary = "老师将学生加入到班级")
    @PostMapping("/teacher-add")
    public R<Long> teacherAddStudent(@Validated @RequestBody ClassStudentCreateDTO dto) {
        classStudentService.teacherAddStudent(dto);
        return R.ok("添加成功");
    }

    /**
     * 老师移除班级主学生，注意：调错接口、传错值删除不生效
     *
     * @param classId     班级id
     * @param assistantId 助教id
     * @return Boolean
     */
    @Operation(summary = "老师移除班级助教")
    @PostMapping("/{classId}/{assistantId}/teacher-remove-assistant")
    public R<Boolean> teacherRemoveAssistant(@PathVariable("classId") Long classId, @PathVariable("assistantId") Long assistantId) {
        return R.data(classStudentService.teacherRemoveAssistant(LoginHelper.getXqLoginUser(), classId, assistantId), "移除成功");
    }

    /**
     * 老师移除班级主学生，注意：调错接口、传错值删除不生效
     *
     * @param classId 班级id
     * @param dtoList 学生列表
     * @return Boolean
     */
    @Operation(summary = "老师移除班级主学生/批量")
    @PostMapping("/{classId}/teacher-remove-batch")
    public R<Boolean> teacherRemoveMasterBatch(@PathVariable("classId") Long classId, @Validated @RequestBody List<ClassStudentDeleteDTO> dtoList) {
        return R.data(classStudentService.teacherRemoveMasterBatch(LoginHelper.getXqLoginUser(), classId, dtoList), MessageUtils.message("course.class.student.remove.success"));
    }

    /**
     * 老师移除关系学生，注意：调错接口、传错值删除不生效
     *
     * @param classId 班级id
     * @param dtoList 关系学生列表
     * @return Boolean
     */
    @Operation(summary = "老师移除关系学生/批量")
    @PostMapping("/{classId}/teacher-remove-relational-student-batch")
    public R<Boolean> teacherRemoveRelationalStudentBatch(@PathVariable("classId") Long classId, @Validated @RequestBody List<ClassStudentDeleteDTO> dtoList) {
        return R.data(classStudentService.teacherRemoveRelationalStudentBatch(classId, dtoList), "移除成功");
    }

    @Operation(summary = "未进组成员列表")
    @GetMapping("/{classId}/outside-student-list")
    public R<List<ClassStudentResultDTO>> findOutsideStudentList(@PathVariable("classId") Long classId, ClassGroupStudentQueryDTO dto) {
        dto.setClassId(classId);
        List<ClassStudentResultDTO> list = classStudentService.findOutsideStudentList(dto);
        return R.data(list);
    }

    @Operation(summary = "添加助教")
    @PostMapping("/{classId}/add-assistant")
    public R<Long> addAssistant(@PathVariable("classId") Long classId, Long userId) {
        classStudentService.addAssistant(classId, userId);
        return R.ok("添加成功");
    }

    /**
     * TEACHER("TEACHER", "老师"),ASSISTANT("ASSISTANT", "助教"),REPRESENTATIVE("REPRESENTATIVE", "课代表"),STUDENT("STUDENT", "学生");
     */
    @Operation(summary = "模拟用户学生角色设为课代表")
    @PutMapping("/{classStudentId}/student-change-representative")
    public R<Boolean> masterStudentChangeRepresentative(@PathVariable("classStudentId") Long classStudentId, @Validated @RequestBody ClassStudentUpdateDTO dto) {
        dto.setId(classStudentId);
        return R.data(classStudentService.masterStudentChangeRepresentative(dto));
    }

    /**
     * TEACHER("TEACHER", "老师"),ASSISTANT("ASSISTANT", "助教"),REPRESENTATIVE("REPRESENTATIVE", "课代表"),STUDENT("STUDENT", "学生");
     */
    @Operation(summary = "关系用户学生角色设为课代表")
    @PutMapping("/{classStudentId}/relational-student-change-representative")
    public R<Boolean> relationalStudentChangeRepresentative(@PathVariable("classStudentId") Long classStudentId, @Validated @RequestBody ClassStudentUpdateDTO dto) {
        dto.setId(classStudentId);
        return R.data(classStudentService.relationalStudentChangeRepresentative(dto));
    }

    @Operation(summary = "模拟用户课代表角色设置为学生")
    @PutMapping("/{classStudentId}/representative-change-student")
    public R<Boolean> masterRepresentativeChangeStudent(@PathVariable("classStudentId") Long classStudentId, @Validated @RequestBody ClassStudentUpdateDTO dto) {
        dto.setId(classStudentId);
        return R.data(classStudentService.masterRepresentativeChangeStudent(dto));
    }

    @Operation(summary = "关系用户课代表角色设置为学生")
    @PutMapping("/{classStudentId}/relational-representative-change-student")
    public R<Boolean> relationalRepresentativeChangeStudent(@PathVariable("classStudentId") Long classStudentId, @Validated @RequestBody ClassStudentUpdateDTO dto) {
        dto.setId(classStudentId);
        return R.data(classStudentService.relationalRepresentativeChangeStudent(dto));
    }

    /**
     * 已废弃
     */
    @Operation(summary = "学生变为助教")
    @PutMapping("/{id}/student-change-assistant")
    public R<Boolean> studentChangeAssistant(@PathVariable("id") Long id, @Validated @RequestBody ClassStudentUpdateDTO dto) {
        dto.setId(id);
        return R.data(classStudentService.studentChangeAssistant(LoginHelper.getXqLoginUser(), dto));
    }

    /**
     * 已废弃
     */
    @Operation(summary = "助教变为学生")
    @PutMapping("/{id}/assistant-change-student")
    public R<Boolean> assistantChangeStudent(@PathVariable("id") Long id, @Validated @RequestBody ClassStudentUpdateDTO dto) {
        dto.setId(id);
        return R.data(classStudentService.assistantChangeStudent(dto));
    }

    /**
     * 已废弃
     */
    @Operation(summary = "课代表变为助教")
    @PutMapping("/{id}/representative-change-assistant")
    public R<Boolean> representativeChangeAssistant(@PathVariable("id") Long id, @Validated @RequestBody ClassStudentUpdateDTO dto) {
        dto.setId(id);
        return R.data(classStudentService.representativeChangeAssistant(LoginHelper.getXqLoginUser(), dto));
    }

    /**
     * 已废弃
     */
    @Operation(summary = "助教变为课代表")
    @PutMapping("/{id}/assistant-change-representative")
    public R<Boolean> assistantChangeRepresentative(@PathVariable("id") Long id, @Validated @RequestBody ClassStudentUpdateDTO dto) {
        dto.setId(id);
        return R.data(classStudentService.assistantChangeRepresentative(dto));
    }

    @Operation(summary = "查询并添加学生")
    @GetMapping("/{id}/search-and-inset")
    public R<Boolean> searchAndInsertStudent(@PathVariable("id") Long id, String searchKey, ClassAuditJsonParamDTO auditContent) {
        return R.data(classStudentService.searchAndInsertStudent(id, searchKey, auditContent));
    }

    @Operation(summary = "查询自己的加课数量")
    @GetMapping("/find-added-class-count")
    public R<ClassStudentAddedCountResultDTO> findAddedClassCount() {
        int addedClassCount = classStudentService.findAddedClassCount();
        return R.data(ClassStudentAddedCountResultDTO.of(addedClassCount));
    }

    /**
     * 根据班级id查询模拟用户总人数
     *
     * @param classId 班级id
     * @return Long
     */
    @Operation(summary = "根据班级id查询模拟用户总人数")
    @GetMapping("/{classId}/find-class-student-count")
    public R<Long> findClassStudentCountByClassId(@PathVariable("classId") Long classId) {
        Long count = classStudentService.findClassStudentCountByClassId(classId);
        return R.data(count);
    }

    /**
     * 根据班级id查询班级总人数（包括老师、助教、关系用户）
     *
     * @param classId 班级id
     * @return Long
     */
    @Operation(summary = "根据班级id查询班级总人数（包括老师、助教、关系用户）")
    @GetMapping("/{classId}/find-all-count")
    public R<Long> findAllCountByClassId(@PathVariable("classId") Long classId) {
        Long count = classStudentService.findAllCountByClassId(classId);
        return R.data(count);
    }

    /**
     * 根据班级id查询班级总学生(只统计模拟主学生)
     *
     * @param classId 班级id
     * @return Long
     */
    @Operation(summary = "根据班级id查询班级总学生(只统计模拟主学生)")
    @GetMapping("/{classId}/find-class-master-student-list")
    public R<List<ClassStudentResultDTO>> findClassMasterStudentByClassId(@PathVariable("classId") Long classId) {
        List<ClassStudentResultDTO> list = classStudentService.findClassMasterStudentByClassId(classId);
        return R.data(list);
    }

    /**
     * 根据班级id列表查询班级总学生(只统计模拟主学生)
     *
     * @param classIdList 班级id列表
     * @return Long
     */
    @Operation(summary = "根据班级id列表查询班级总学生(只统计模拟主学生)")
    @PostMapping("/find-class-master-student-list-by-classIds")
    public R<List<ClassStudentResultDTO>> findClassMasterStudentByClassIdList(@RequestBody List<Long> classIdList) {
        List<ClassStudentResultDTO> list = classStudentService.findClassMasterStudentByClassIdList(classIdList);
        return R.data(list);
    }

    @Operation(summary = "根据班级id和模拟学生的学生id查询关系学生列表")
    @GetMapping("/{classId}/{studentId}/find-imitate-student-list")
    public R<List<ClassStudentResultDTO>> findRelationStudentByClassIdAndImitateStudentId(@PathVariable("classId") Long classId, @PathVariable("studentId") Long studentId) {
        List<ClassStudentResultDTO> relationshipStudentlist = classStudentService.findRelationStudentByClassIdAndImitateStudentId(classId, studentId);
        return R.data(relationshipStudentlist);
    }

    /**
     * 根据班级id和关系用户id查询用户信息(可以查老师)
     */
    @GetMapping("/find-class-student-contain-teacher/{classId}/{userId}")
    public R<ClassStudentResultDTO> findClassStudentContainTeacherByClassIdAndUserId(@PathVariable("classId") Long classId, @PathVariable("userId") Long userId) {
        return R.data(classStudentService.findClassStudentContainTeacherByClassIdAndUserId(classId, userId));
    }

    /**
     * 支持前端做填充
     *
     * @param classId 班级id
     * @return 手机号吗列表
     */
    @Operation(summary = "根据班级id和模拟学生姓名查询模拟学生手机号码列表")
    @PostMapping("/{classId}/find-imitate-mobile-list")
    public R<List<ClassStudentMobileResultDTO>> findImitateStudentMobileList(@PathVariable("classId") Long classId, @Validated @RequestBody ClassImitateStudentQueryDTO dto) {
        dto.setClassId(classId);
        List<ClassStudentMobileResultDTO> imitateStudentMobileList = classStudentService.findImitateStudentMobileList(dto);
        return R.data(imitateStudentMobileList);
    }

    /**
     * 只补充缺失的
     *
     * @param dto
     * @return
     */
    @Operation(summary = "登录用户（关系用户）补充学生报名信息")
    @PutMapping("/{classId}/repair-audit-content")
    public R<Void> repairAuditContent(@PathVariable("classId") Long classId, @Validated @RequestBody ClassStudentAuditData dto) {
        classStudentService.repairAuditContent(classId, dto);
        return R.ok("修改成功");
    }
}
